<template>
  <div :class="prefix" id="container"></div>
</template>

<script setup lang="ts">
import { onMounted, onUnmounted, ref } from 'vue';
import { getTextWidth } from '@/utils/textWidth';
import G6 from '@antv/g6';
import { data2 } from '../config';

const prefix = 'basicShapes';

const graph = ref(null);

const initGraph = () => {
  setNodeStyle();

  // 获取盒子宽高
  const width = document.getElementById('container').scrollWidth;
  const height = document.getElementById('container').scrollHeight;

  // 生成G6对象
  graph.value = new G6.Graph({
    container: 'container',
    width,
    height,
    fitCenter: true,
    modes: {
      default: ['drag-canvas', 'zoom-canvas'],
    },
    layout: {
      type: 'force', // 指定为力导向布局，此处可以使用force2，具体参考官方api
      preventOverlap: true, // 防止节点重叠
      linkDistance: 400, // 指定边距离为150
      nodeSpacing: 85, // 防止重叠时节点边缘间距的最小值
      alpha: 1, // 当前的迭代收敛阈值
      alphaDecay: 0.05, // 迭代阈值的衰减率，收敛阈值衰减为0时图谱不会迭代，节点之间不存在作用力。范围 [0, 1]，迭代阈值为0时图谱可以一直保持迭代状态，即：图谱会一直保持动态力导状态
    },
    defaultEdge: {
      style: {
        endArrow: {
          path: G6.Arrow.triangle(4, 4, 2),
          d: 2,
          fill: '#2EA1FF',
        },
      },
    },
    // fitViewPadding: [20],
  });

  // 被拖动时触发
  graph.value.on('node:dragstart', (e) => {
    graph.value.layout();
    refreshDragedNodePosition(e);
  });

  // 节点拖动时触发
  graph.value.on('node:drag', (e) => {
    refreshDragedNodePosition(e);
  });

  // 事件在用户拖动节点并释放鼠标时触发。
  graph.value.on('node:dragend', function (e) {
    e.item.get('model').fx = null;
    e.item.get('model').fy = null;
  });

  if (typeof window !== 'undefined')
    window.onresize = () => {
      if (!graph.value || graph.value.get('destroyed')) return;
      if (!document.getElementById('container') || !document.getElementById('container').scrollWidth || !document.getElementById('container').scrollHeight) return;
      graph.value.changeSize(document.getElementById('container').scrollWidth, document.getElementById('container').scrollHeight);
    };

  // 解决拖动产生残影问题
  graph.value.get('canvas').set('localRefresh', false);

  graph.value.data(data2);
  graph.value.render();
};

// 02-自定义节点样式
const setNodeStyle = () => {
  G6.registerNode('node2Style', {
    draw(cfg, group) {
      console.log(cfg);
      const r = 2;
      const color = '#fff';
      const w = getTextWidth(cfg.label);
      const h = 50;
      const shape = group.addShape('rect', {
        attrs: {
          x: -w / 2 - 20,
          y: -h / 2,
          width: w + 40,
          height: h,
          stroke: 'rgb(221, 222, 226)',
          lineWidth: 1,
          radius: r,
          fill: '#fff',
          shadowColor: 'rgb(221, 222, 226)',
          shadowBlur: 20,
        },

        name: 'node2Style-main',
        // draggable: true,
      });

      group.addShape('text', {
        attrs: {
          x: -w / 2,
          y: -h / 2 + h / 2,
          text: cfg.label,
          fill: '#0e66e9',
          fontSize: 14,
          fontFamily: 'iconfont',
          textAlign: 'left',
          textBaseline: 'middle',
        },
        // draggable: true,
      });

      group.addShape('text', {
        attrs: {
          x: 1 - getTextWidth(cfg.subLabel) / 2,
          y: h - 14,
          text: cfg.subLabel,
          fill: '#000',
          fontSize: 14,
          fontFamily: 'iconfont',
          textAlign: 'left',
          textBaseline: 'middle',
        },
        // draggable: true,
      });

      return shape;
    },
  });
};

function refreshDragedNodePosition(e) {
  const model = e.item.get('model');
  model.fx = e.x;
  model.fy = e.y;
}

onMounted(() => {
  initGraph();
});

onUnmounted(() => {
  if (graph.value) {
    // 清空数据（可省略）
    graph.value.clear();
    // 销毁画布
    graph.value.destroy();
    // 将画布实例对象置空
    graph.value = null;
  }
});
</script>

<style lang="scss" scoped>
.basicShapes {
  width: 100%;
  height: calc($height - 40px);
}
</style>
